﻿﻿using System.Text;

namespace PTop.Code
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;

    /// <summary>
    /// 反射工具类
    /// </summary>
    public static class ObjectReflectionHelper
    {
        #region 查找方法

        /// <summary>
        /// 根据名称获得类型
        /// </summary>
        /// <param name="name">类名称</param>
        /// <param name="ignoreCase">忽略大小写</param>
        /// <param name="packageFilter">包名过滤器</param>
        /// <returns></returns>
        public static IList<Type> GetTypesByName(this string name, bool ignoreCase = false, string packageFilter = null)
        {
            var types = new List<Type>();
            var stringComparison = ignoreCase ? StringComparison.CurrentCultureIgnoreCase : StringComparison.CurrentCulture;
            var isFilter = !string.IsNullOrEmpty(packageFilter);

            foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
            {
                // 此步骤是必须的，否则会引发错误：动态程序集中不支持已调用的成员(The invoked member is not supported in a dynamic assembly)
                if (a.IsDynamic) continue;

                foreach (var t in a.GetExportedTypes())
                {
                    if (t.FullName.Equals(name, stringComparison) || t.Name.Equals(name, stringComparison))
                    {
                        if (isFilter)
                        {
                            if (t.FullName.IndexOf(packageFilter, StringComparison.Ordinal) > -1)
                                types.Add(t);
                        }
                        else
                        {
                            types.Add(t);
                        }
                    }
                }
            }
            return types;
        }

        #endregion

        /// <summary>
        /// 判断对象是否为组合模型
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        private static bool IsFromObjectContainer(Type type)
        {
            return type.ContainsInterface("ICompositeObject");
        }

        #region Object的辅助方法

        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <param name="value">对象实例</param>
        /// <param name="propertyName">属性名称</param>
        /// <param name="ignoreError">是否忽略操作错误</param>
        /// <returns>属性值</returns>
        public static object GetPropertyValue<T>(this T value, string propertyName,
                                                 bool ignoreError = true)
        {
            if (Equals(value, null))
            {
                throw new ArgumentNullException("value");
            }
            if (propertyName == null)
            {
                throw new ArgumentNullException("propertyName");
            }

            try
            {

                var type = value.GetType();
                if (IsFromObjectContainer(type))
                {
                    var fi = type.GetField("_property" + propertyName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.SetField);
                    return fi.GetValue(value);
                }

                var pi = value.GetType().GetExistProperty(propertyName);
                return pi.GetValue(value, null);
            }
            catch (Exception)
            {
                if (ignoreError) return null;
                throw;
            }
        }

        /// <summary>
        /// 获取属性
        /// </summary>
        /// <param name="value">对象实例</param>
        /// <param name="propertyName">属性名称</param>
        /// <param name="ignoreError">是否忽略操作错误</param>
        /// <returns>属性值</returns>
        public static PropertyInfo GetProperty<T>(this T value, string propertyName,
                                                  bool ignoreError = true)
        {
            if (Equals(value, null))
            {
                throw new ArgumentNullException("value");
            }
            if (propertyName == null)
            {
                throw new ArgumentNullException("propertyName");
            }

            try
            {
                return value.GetType().GetPropertyEx(propertyName);
            }
            catch (Exception)
            {
                if (ignoreError) return null;
                throw;
            }
        }

        /// <summary>
        /// 获取属性
        /// </summary>
        /// <param name="value">对象实例</param>
        /// <param name="ignoreError">是否忽略操作错误</param>
        /// <returns>属性值</returns>
        public static PropertyInfo[] GetProperties<T>(bool ignoreError = true)
        {
            try
            {
                Type type = typeof(T);
                try
                {
                    var pis = type.GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance);
                    return pis;
                }
                catch (AmbiguousMatchException)
                {
                    return type.GetProperties();
                }
            }
            catch (Exception)
            {
                if (ignoreError) return null;
                throw;
            }
        }

        /// <summary>
        /// 获取属性
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="ignoreError">是否忽略操作错误</param>
        /// <returns>属性值</returns>
        public static PropertyInfo[] GetProperties(Type type, bool ignoreError = true)
        {
            try
            {
                try
                {
                    var pis = type.GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance);
                    return pis;
                }
                catch (AmbiguousMatchException)
                {
                    return type.GetProperties();
                }
            }
            catch (Exception)
            {
                if (ignoreError) return null;
                throw;
            }
        }

        /// <summary>
        /// 设置属性值
        /// </summary>
        /// <param name="value">对象实例</param>
        /// <param name="propertyName">属性名称</param>
        /// <param name="propertyValue">属性值</param>
        /// <param name="ignoreError">是否忽略操作错误</param>
        /// <returns>操作是否成功</returns>
        public static bool SetPropertyValue<T>(this T value, string propertyName,
                                               object propertyValue, bool ignoreError = true)
        {
            if (Equals(value, null))
            {
                throw new ArgumentNullException("value");
            }
            if (propertyName == null)
            {
                throw new ArgumentNullException("propertyName");
            }

            try
            {
                var type = value.GetType();
                if (IsFromObjectContainer(type))
                {
                    var fi = type.GetField("_property" + propertyName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.SetField);
                    if (fi != null) fi.SetValue(value, propertyValue);
                }
                else
                {
                    var pi = value.GetType().GetExistProperty(propertyName);
                    if (pi != null) pi.SetValue(value, propertyValue, null);
                }
                //value.GetType().InvokeMember(propertyName, BindingFlags.SetProperty,
                //    null, value, new[] { propertyValue });
                return true;
            }
            catch
            {
                return ignoreError;
            }
        }

        /// <summary>
        /// 调用方法
        /// </summary>
        /// <param name="value">对象实例</param>
        /// <param name="methodName">方法名</param>
        /// <param name="ignoreError">是否忽略操作错误</param>
        /// <returns>操作是否成功</returns>
        public static bool CallMethod<T>(this T value, string methodName,
                                         bool ignoreError = true)
        {
            if (Equals(value, null))
            {
                throw new ArgumentNullException("value");
            }
            if (methodName == null)
            {
                throw new ArgumentNullException("methodName");
            }

            try
            {
                value.GetType().GetMethod(methodName).Invoke(value, null);
                return true;
            }
            catch
            {
                return ignoreError;
            }
        }

        /// <summary>
        /// 调用方法
        /// </summary>
        /// <param name="value">对象实例</param>
        /// <param name="methodName">方法名</param>
        /// <param name="pValues">参数值</param>
        /// <param name="ignoreError">是否忽略操作错误</param>
        /// <returns>操作是否成功</returns>
        public static bool CallMethod<T>(this T value, string methodName,
                                         object[] pValues, bool ignoreError = true)
        {
            if (Equals(value, null) || methodName == null) return false;
            try
            {
                value.GetType().GetMethod(methodName).Invoke(value, pValues);
                return true;
            }
            catch
            {
                return ignoreError;
            }
        }

        #endregion

        #region Class的辅助方法

        /// <summary>
        /// 判断某个对象是否含有某个属性名
        /// </summary>
        /// <param name="value">对象实例</param>
        /// <param name="propertyName">属性名称</param>
        /// <returns>属性值</returns>
        public static bool HasProperty<T>(this T value, string propertyName)
        {
            if (Equals(value, null))
            {
                throw new ArgumentNullException("value");
            }
            if (propertyName == null)
            {
                throw new ArgumentNullException("propertyName");
            }
            return value.GetType().GetPropertyEx(propertyName) != null;
        }

        /// <summary>
        /// 获取某个对象中所有包含某个Attribute标记的属性的值
        /// </summary>
        /// <typeparam name="T">Attribute</typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        public static IDictionary<string, object> GetPropertyValuesInclude<T>(
            this object value) where T : Attribute
        {
            if (value == null) return null;

            return value.GetType().GetProperties()
                .Where(pi => pi.GetCustomAttributes(typeof(T), true).Length > 0)
                .ToDictionary(pi => pi.Name, pi => pi.GetValue(value, null));
        }

        /// <summary>
        /// 获取某个对象中所有不包含某个Attribute标记的属性的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        public static IDictionary<string, object> GetPropertyValuesExclude<T>(
            this object value) where T : Attribute
        {
            if (value == null) return null;

            return value.GetType().GetProperties()
                .Where(pi => pi.GetCustomAttributes(typeof(T), true).Length == 0)
                .ToDictionary(pi => pi.Name, pi => pi.GetValue(value, null));
        }

        #endregion

        #region PropertyInfo的辅助方法

        /// <summary>
        /// 属性是否包含自定义属性
        /// </summary>
        /// <typeparam name="T">属性泛型</typeparam>
        /// <param name="pi"></param>
        /// <returns></returns>
        public static bool HasAttribute<T>(this PropertyInfo pi) where T : Attribute
        {
            if (pi == null) return false;
            return (pi.GetCustomAttributes(typeof(T), true).Length > 0);
        }

        /// <summary>
        /// 类型是否包含自定义属性
        /// </summary>
        /// <typeparam name="T">类型泛型</typeparam>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool HasAttribute<T>(this Type type) where T : Attribute
        {
            return (type.GetCustomAttributes(typeof(T), true).Length > 0);
        }

        /// <summary>
        /// 方法是否包含自定义属性
        /// </summary>
        /// <typeparam name="T">属性泛型</typeparam>
        /// <param name="mi"></param>
        /// <returns></returns>
        public static bool HasAttribute<T>(this MethodInfo mi) where T : Attribute
        {
            if (mi == null) return false;
            return (mi.GetCustomAttributes(typeof(T), true).Length > 0);
        }

        /// <summary>
        /// 返回包含的属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="pi"></param>
        /// <returns></returns>
        public static T GetAttribute<T>(this PropertyInfo pi)
            where T : Attribute
        {
            if (pi == null) return default(T);
            var attrs = pi.GetCustomAttributes(typeof(T), true);
            return attrs.Length == 0 ? null : (T)attrs[0];
        }

        /// <summary>
        /// 返回包含的属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="mi"></param>
        /// <returns></returns>
        public static T GetAttribute<T>(this MethodInfo mi)
            where T : Attribute
        {
            if (mi == null) return default(T);
            var attrs = mi.GetCustomAttributes(typeof(T), false);
            return attrs.Length == 0 ? null : (T)attrs[0];
        }

        #endregion

        #region Type的辅助方法

        /// <summary>
        /// 获得类型的属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="type"></param>
        /// <returns></returns>
        public static T GetAttribute<T>(this Type type) where T : Attribute
        {
            object[] attrs = type.GetCustomAttributes(typeof(T), true);
            return attrs.Length == 0 ? null : (T)attrs[0];
        }

        /// <summary>
        /// 获得类自身的属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="type"></param>
        /// <returns></returns>
        public static T GetSelfAttribute<T>(this Type type) where T : Attribute
        {
            object[] attrs = type.GetCustomAttributes(typeof(T), false);
            return attrs.Length == 0 ? null : (T)attrs[0];
        }

        /// <summary>
        /// 返回包含的属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="type"></param>
        /// <returns></returns>
        public static Attribute[] GetAttributes<T>(this Type type) where T : Attribute
        {
            object[] attrs = type.GetCustomAttributes(typeof(T), true);
            return attrs.Length == 0 ? new Attribute[] { } : (Attribute[])attrs;
        }

        /// <summary>
        /// 获取属性的扩展方法，可获取重定义的新属性
        /// </summary>
        /// <param name="type"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public static PropertyInfo GetPropertyEx(this Type type, string propertyName)
        {
            if (propertyName == null) return null;
            PropertyInfo pi = type.GetProperty(propertyName,
                                               BindingFlags.DeclaredOnly | BindingFlags.GetProperty |
                                               BindingFlags.Public | BindingFlags.Instance);
            if (pi != null) return pi;

            try
            {
                pi = type.GetProperty(propertyName,
                                      BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance);
                return pi;
            }
            catch (AmbiguousMatchException)
            {
                foreach (
                    PropertyInfo propertyInfo in
                        type.GetProperties().Where(propertyInfo => propertyInfo.Name.Equals(propertyName)))
                {
                    return propertyInfo;
                }
                throw;
            }
        }

        /// <summary>
        /// 获得所有的属性
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static IList<Type> GetAllInterfaces(this Type type)
        {
            var list = new List<Type>();
            var statck = new Stack<Type>();
            if (type.IsClass)
            {
                foreach (var interfaceType in type.GetInterfaces())
                {
                    statck.Push(interfaceType);
                }
            }
            else if (type.IsInterface)
            {
                statck.Push(type);
            }
            while (statck.Count > 0)
            {
                var interfaceType = statck.Pop();
                if (!list.Contains(interfaceType)) list.Add(interfaceType);
                foreach (var innerType in interfaceType.GetInterfaces())
                {
                    statck.Push(innerType);
                }
            }
            return list;
        }

        /// <summary>
        /// 获得所有的属性
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static IList<PropertyInfo> GetAllProperties(this Type type)
        {
            if (type.IsClass)
            {
                return type.GetProperties();
            }

            if (type.IsInterface)
            {
                var list = new List<PropertyInfo>();
                var statck = new Stack<Type>();
                statck.Push(type);
                while (statck.Count > 0)
                {
                    var interfaceType = statck.Pop();
                    foreach (var innerType in interfaceType.GetInterfaces())
                    {
                        statck.Push(innerType);
                    }
                    list.AddRange(interfaceType.GetProperties());
                }
                return list.Distinct().ToList();
            }
            return null;
        }

        /// <summary>
        /// 是否包含接口
        /// </summary>
        /// <typeparam name="TInterface"></typeparam>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool ContainsInterface<TInterface>(this Type type)
        {
            return ContainsInterface(type, typeof(TInterface));
        }

        /// <summary>
        /// 是否包含接口
        /// </summary>
        /// <param name="type"></param>
        /// <param name="interfaceTypeFullName"></param>
        /// <returns></returns>
        public static bool ContainsInterface(this Type type, string interfaceTypeFullName)
        {
            if (type.IsClass)
            {
                return type.GetInterface(interfaceTypeFullName) != null;
            }

            if (type.IsInterface)
            {
                var statck = new Stack<Type>();
                statck.Push(type);
                while (statck.Count > 0)
                {
                    var tmpType = statck.Pop();
                    if (tmpType.GetInterface(interfaceTypeFullName) != null) return true;
                    foreach (var innerType in tmpType.GetInterfaces())
                    {
                        statck.Push(innerType);
                    }
                }
            }

            return false;
        }

        /// <summary>
        /// 是否包含接口
        /// </summary>
        /// <param name="type"></param>
        /// <param name="interfaceType"></param>
        /// <returns></returns>
        public static bool ContainsInterface(this Type type, Type interfaceType)
        {
            if (type.IsClass)
            {
                return type.GetInterface(interfaceType.FullName) == interfaceType;
            }

            if (type.IsInterface)
            {
                var statck = new Stack<Type>();
                statck.Push(type);
                while (statck.Count > 0)
                {
                    var tmpType = statck.Pop();
                    if (tmpType.GetInterface(interfaceType.FullName) == interfaceType) return true;
                    foreach (var innerType in tmpType.GetInterfaces())
                    {
                        statck.Push(innerType);
                    }
                }
            }

            return false;
        }

        /// <summary>
        /// 获取存在的属性的属性信息
        /// </summary>
        /// <param name="type"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public static PropertyInfo GetExistProperty(this Type type, string propertyName)
        {
            if (propertyName == null)
            {
                throw new ArgumentNullException("propertyName");
            }

            if (type.IsClass)
            {

                var pi = type.GetProperty(propertyName,
                    BindingFlags.DeclaredOnly | BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance);
                if (pi != null) return pi;

                try
                {
                    pi = type.GetProperty(propertyName, BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance);
                    return pi;
                }
                catch (AmbiguousMatchException)
                {
                    foreach (var propertyInfo in type.GetProperties().Where(propertyInfo => propertyInfo.Name.Equals(propertyName)))
                    {
                        return propertyInfo;
                    }
                    throw;
                }
            }

            if (type.IsInterface)
            {
                var statck = new Stack<Type>();
                statck.Push(type);
                while (statck.Count > 0)
                {
                    var interfaceType = statck.Pop();

                    var properties = interfaceType.GetProperties();
                    foreach (var property in properties)
                    {
                        if (property.Name.Equals(propertyName)) return property;
                    }

                    foreach (var innerType in interfaceType.GetInterfaces())
                    {
                        statck.Push(innerType);
                    }
                }
                throw new ArgumentException("property name " + propertyName + " not exist", "propertyName");
            }

            throw new ArgumentException(type.FullName + " is not class or interface");
        }

        #endregion



        /// ------------------------------------------------------------------------
        /// <summary>
        /// Deep Comparison two objects if they are alike. The objects are consider alike if 
        /// they are:
        /// <list type="ordered">
        ///    <item>of the same <see cref="System.Type"/>,</item>
        ///    <item>have the same number of methods, properties and fields</item>
        ///    <item>the public and private properties and fields values reflect each other's. </item>
        /// </list>
        /// </summary>
        /// <param name="original"></param>
        /// <param name="comparedToObject"></param>
        /// <returns></returns>
        /// ------------------------------------------------------------------------
        public static bool IsALike(object original, object comparedToObject)
        {

            if (original.GetType() != comparedToObject.GetType())
                return false;

            // ...............................................
            // Compare Number of Private and public Methods
            // ...............................................
            MethodInfo[] originalMethods = original
              .GetType()
              .GetMethods(BindingFlags.Instance |
              BindingFlags.NonPublic |
              BindingFlags.Public);

            MethodInfo[] comparedMethods = comparedToObject
              .GetType()
              .GetMethods(BindingFlags.Instance |
              BindingFlags.NonPublic |
              BindingFlags.Public);

            if (comparedMethods.Length != originalMethods.Length)
                return false;

            // ...............................................
            // Compare Number of Private and public Properties
            // ................................................
            PropertyInfo[] originalProperties = original
              .GetType()
              .GetProperties(BindingFlags.Instance |
              BindingFlags.NonPublic |
              BindingFlags.Public);

            PropertyInfo[] comparedProperties = comparedToObject
              .GetType()
              .GetProperties(BindingFlags.Instance |
              BindingFlags.NonPublic |
              BindingFlags.Public);


            if (comparedProperties.Length != originalProperties.Length)
                return false;


            // ...........................................
            // Compare number of public and private fields
            // ...........................................
            FieldInfo[] originalFields = original
              .GetType()
              .GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

            FieldInfo[] comparedToFields = comparedToObject
              .GetType()
              .GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);


            if (comparedToFields.Length != originalFields.Length)
                return false;

            // ........................................
            // compare field values
            // ........................................
            foreach (FieldInfo fi in originalFields)
            {

                // check to see if the object to contains the field          
                FieldInfo fiComparedObj = comparedToObject.GetType().GetField(fi.Name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

                if (fiComparedObj == null)
                    return false;

                // Get the value of the field from the original object        
                Object srcValue = original.GetType().InvokeMember(fi.Name,
                  BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public,
                  null,
                  original,
                  null);



                // Get the value of the field
                object comparedObjFieldValue = comparedToObject
                  .GetType()
                  .InvokeMember(fiComparedObj.Name,
                  BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public,
                  null,
                  comparedToObject,
                  null);


                // -------------------------------
                // now compare the field values
                // -------------------------------

                if (srcValue == null)
                {
                    return comparedObjFieldValue == null;
                }

                if (srcValue.GetType() != comparedObjFieldValue.GetType())
                    return false;

                if (!srcValue.ToString().Equals(comparedObjFieldValue.ToString()))
                    return false;
            }

            // ........................................
            // compare each Property values
            // ........................................
            foreach (PropertyInfo pi in originalProperties)
            {

                // check to see if the object to contains the field          
                PropertyInfo piComparedObj = comparedToObject
                  .GetType()
                  .GetProperty(pi.Name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

                if (piComparedObj == null)
                    return false;

                // Get the value of the property from the original object        
                Object srcValue = original
                  .GetType()
                  .InvokeMember(pi.Name,
                  BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public,
                  null,
                  original,
                  null);

                // Get the value of the property
                object comparedObjValue = comparedToObject
                  .GetType()
                  .InvokeMember(piComparedObj.Name,
                  BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public,
                  null,
                  comparedToObject,
                  null);


                // -------------------------------
                // now compare the property values
                // -------------------------------
                if (srcValue.GetType() != comparedObjValue.GetType())
                    return false;

                if (!srcValue.ToString().Equals(comparedObjValue.ToString()))
                    return false;
            }
            return true;
        }



        /// <summary>
        /// Dumps the properties names and current values
        /// from an object
        /// </summary>
        /// <param name="Object">Object to dunp</param>
        /// <returns>An HTML formatted table containing the information about the object</returns>
        public static string DumpProperties(object Object)
        {
            try
            {
                var tempValue = new StringBuilder();
                tempValue.Append("<table><thead><tr><th>Property Name</th><th>Property Value</th></tr></thead><tbody>");
                var objectType = Object.GetType();
                var properties = objectType.GetProperties();
                foreach (var property in properties)
                {
                    tempValue.Append("<tr><td>" + property.Name + "</td><td>");
                    var parameters = property.GetIndexParameters();
                    if (property.CanRead && parameters.Length == 0)
                    {
                        try
                        {
                            var value = property.GetValue(Object, null);
                            tempValue.Append(value == null ? "null" : value.ToString());
                        }
                        catch { }
                    }
                    tempValue.Append("</td></tr>");
                }
                tempValue.Append("</tbody></table>");
                return tempValue.ToString();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }
        /// <summary>
        /// Dumps the properties names and current values
        /// from an object type (used for static classes)
        /// </summary>
        /// <param name="objectType">Object type to dunp</param>
        /// <returns>An HTML formatted table containing the information about the object type</returns>
        public static string DumpProperties(Type objectType)
        {
            try
            {
                var tempValue = new StringBuilder();
                tempValue.Append("<table><thead><tr><th>Property Name</th><th>Property Value</th></tr></thead><tbody>");
                var properties = objectType.GetProperties();
                foreach (var property in properties)
                {
                    tempValue.Append("<tr><td>" + property.Name + "</td><td>");
                    if (property.GetIndexParameters().Length == 0)
                    {
                        try
                        {
                            tempValue.Append(property.GetValue(null, null) == null ? "null" : property.GetValue(null, null).ToString());
                        }
                        catch
                        { }
                    }
                    tempValue.Append("</td></tr>");
                }
                tempValue.Append("</tbody></table>");
                return tempValue.ToString();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }
        /// <summary>
        /// Returns all assemblies and their properties
        /// </summary>
        /// <returns>An HTML formatted string that contains the assemblies and their information</returns>
        public static string DumpAllAssembliesAndProperties()
        {
            var builder = new StringBuilder();
            var assemblies = AppDomain.CurrentDomain.GetAssemblies();
            foreach (var assembly in assemblies)
            {
                builder.Append("<strong>" + assembly.GetName().Name + "</strong><br />");
                builder.Append(DumpProperties(assembly) + "<br /><br />");
            }
            return builder.ToString();
        }

        /// <summary>
        /// 创建对象实例
        /// </summary>
        /// <typeparam name="T">要创建对象的类型</typeparam>
        /// <param name="assemblyName">类型所在程序集名称</param>
        /// <param name="nameSpace">类型所在命名空间</param>
        /// <param name="className">类型名</param>
        /// <returns></returns>
        public static T CreateInstance<T>(string assemblyName, string nameSpace, string className)
        {
            try
            {
                string fullName = nameSpace + "." + className;//命名空间.类型名
                var assembly = Assembly.Load(assemblyName);//加载程序集，创建程序集里面的 命名空间.类型名 实例
                object ect = assembly.CreateInstance(fullName, true);

                return (T)ect;//类型转换并返回

            }
            catch (Exception ex)
            {
                //发生异常，返回类型的默认值
                return default(T);
            }
        }
    }
}